home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
AddOns
/
WormWars
/
Source
/
system.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-08
|
85KB
|
2,722 lines
/* $Filename: WormWars/Source/system.c $
* $VER: Worm Wars 4.1 (1.6.99) $
* $Description: Amiga-specific code for Worm Wars 4.1 for Amiga $
*
* © Copyright 1999 James R. Jacobs.
* Freely distributable.
*
* Prerelease version.
* _
* // -=AMIGA=-
* //
* _ //
* \\ //
* \X/
#INCLUDES -------------------------------------------------------------- */
#include "system.h" // #includes everything else
// GLOBAL VARIABLES (owned by engine.c, imported by amiga.lib) ------------
AGLOBAL struct Library* TimerBase = NULL;
// EXTERNAL VARIABLES (owned by engine.c, imported by system.c) -----------
IMPORT struct Library* SysBase;
IMPORT ABOOL clearthem, modified;
IMPORT SBYTE a, board[MAXLEVELS + 1][FIELDX + 1][FIELDY + 1],
brush, eachworm[4][2][9],
field[FIELDX + 1][FIELDY + 1],
hi, level, levels, lo,
startx[MAXLEVELS + 1], starty[MAXLEVELS + 1];
IMPORT STRPTR pathname;
IMPORT SWORD secondsleft, secondsperlevel;
IMPORT ULONG delay, r;
IMPORT struct HiScoreStruct hiscore[HISCORES + 1];
IMPORT struct OrbStruct orb[ORBS + 1];
IMPORT struct TeleportStruct teleport[MAXLEVELS + 1][4];
IMPORT struct WormStruct worm[4];
// MODULE VARIABLES (used only within system.c) ---------------------------
MODULE struct ASLBase* ASLBase = NULL;
MODULE struct GadToolsBase* GadToolsBase = NULL;
MODULE struct GfxBase* GfxBase = NULL;
MODULE struct IntuitionBase* IntuitionBase = NULL;
MODULE struct MEDPlayerBase* MEDPlayerBase = NULL;
MODULE struct FileRequester* ASLRqPtr = NULL;
MODULE ABOOL AudioClosed = TRUE;
MODULE struct MsgPort* AudioPortPtr[4] = {NULL, NULL, NULL, NULL};
MODULE struct IOAudio* AudioRqPtr[4] = {NULL, NULL, NULL, NULL};
MODULE SBYTE Controller = GPCT_NOCONTROLLER;
MODULE struct timeval* CurrentValPtr = NULL;
MODULE struct Gadget* CycleGadgetPtr[4] = {NULL, NULL, NULL, NULL};
MODULE ABOOL eversent[4];
MODULE UBYTE* fbase = NULL;
MODULE ULONG fsize;
MODULE struct FileHandle* FilePtr = NULL;
MODULE ABOOL fxable = FALSE;
MODULE struct InputEvent GameEvent;
MODULE struct Gadget* GListPtr = NULL;
MODULE ABOOL ignore = FALSE;
MODULE ABOOL ignorenextjoy;
MODULE SBYTE InputClosed = TRUE;
MODULE struct MsgPort* InputPortPtr = NULL;
MODULE struct IOStdReq* InputRqPtr = NULL;
MODULE ABOOL joy = FALSE;
MODULE SBYTE JoyClosed = TRUE;
MODULE struct MsgPort* JoyPortPtr = NULL;
MODULE struct IOStdReq* JoyRqPtr = NULL;
MODULE ULONG length[SAMPLES + 1][2];
MODULE struct Window* MainWindowPtr = NULL;
MODULE ABOOL menu = FALSE;
MODULE struct Menu* MenuPtr = NULL;
MODULE SBYTE mode = FALSE;
MODULE ABOOL musicable = FALSE;
MODULE SBYTE OldPri = 0;
MODULE APTR OldWindowPtr = NULL;
MODULE struct timeval* PausedValPtr = NULL;
MODULE struct Gadget* PrevGadgetPtr = NULL;
MODULE struct Process* ProcessPtr = NULL;
MODULE ULONG receipter[4] = {(ULONG) -1, (ULONG) -1, (ULONG) -1, (ULONG) -1};
MODULE UBYTE* sbase[SAMPLES + 1];
MODULE struct Screen* ScreenPtr = NULL;
MODULE struct MMD0* SongPtr = NULL;
MODULE ULONG speed[SAMPLES + 1];
MODULE ULONG ssize[SAMPLES + 1];
MODULE struct timeval* StartValPtr = NULL;
MODULE ABOOL sticky = FALSE;
MODULE struct Gadget* StringGadgetPtr[6] = {NULL, NULL, NULL, NULL, NULL};
MODULE SBYTE TimerClosed = TRUE;
MODULE struct MsgPort* TimerPortPtr = NULL;
MODULE struct timerequest* TimerRqPtr = NULL;
MODULE struct VisualInfo* VisualInfoPtr = NULL;
MODULE ULONG yes[SAMPLES + 1];
MODULE struct TextAttr Topaz8 =
{ (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
};
// FUNCTIONS --------------------------------------------------------------
int main(int argc, char** argv)
{
ABOOL argument = FALSE, success = FALSE;
SBYTE counter, i, player, which;
TEXT errormessage[SAYLIMIT + 1];
LONG NewPri;
UWORD Pens[10] = {BLACK, WHITE, WHITE, WHITE, DARKGREY, PURPLE, BLACK, BLACK, BLUE, (UWORD) ~0};
struct ColorSpec Colours[21] =
{ /* colour red green blue description */
{ 0, 0x0, 0x0, 0x0}, // BLACK
{ 1, 0xF, 0xF, 0xF}, // WHITE
{ 2, 0x2, 0x2, 0x2}, // DARKGREY
{ 3, 0x6, 0x6, 0x6}, // medium grey
{ 4, 0xA, 0xA, 0xA}, // LIGHTGREY
{ 5, 0xE, 0x8, 0x3}, // ORANGE
{ 6, 0xA, 0x2, 0xA}, // PURPLE
{ 7, 0x8, 0x4, 0x2}, // brown
{ 8, 0x3, 0x9, 0x3}, // DARKGREEN
{ 9, 0x4, 0xE, 0x4}, // light GREEN
{ 10, 0xF, 0x1, 0x1}, // DARKRED
{ 11, 0xF, 0x4, 0x4}, // light RED
{ 12, 0x3, 0x3, 0xF}, // DARKBLUE
{ 13, 0x6, 0x6, 0xF}, // light BLUE
{ 14, 0xA, 0x8, 0x3}, // DARKYELLOW
{ 15, 0xC, 0xC, 0x2}, // light YELLOW
{ 16, 0x0, 0x0, 0x0}, // pointer: transparent
{ 17, 0xE, 0x4, 0x4}, // pointer: fill
{ 18, 0x3, 0x3, 0x3}, // pointer: shadow
{ 19, 0xC, 0xC, 0xC}, // pointer: shine
{ -1, NULL, NULL, NULL
} };
UBYTE* p8data;
SBYTE code = 0;
SBYTE iobuffer[8]; // buffer for 8SVX.VHDR
SBYTE* psample[2]; // sample pointers
struct Chunk* p8Chunk; // pointers for 8SVX parsing
Voice8Header* pVoice8Header;
ULONG rd8count;
/* Start of program.
version embedding into executable */
if (0) // that is, never
say(VERSION, ANYTHING);
ProcessPtr = (struct Process *) FindTask(NULL);
// argument parsing
if (argc == 2 && argv[1][0] == '?' && argv[1][1] == '\0')
{ printf("Usage: %s [-p<priority>] [<fieldset>]\n", argv[0]);
cleanexit(EXIT_SUCCESS);
}
if (argc >= 2)
for (i = 1; i <= argc - 1; i++)
if (argv[i][0] == '-' && (argv[i][1] == 'p' || argv[i][1] == 'P'))
{ stcd_l(&argv[i][2], &NewPri);
if (NewPri >= -5 && NewPri <= 5)
OldPri = SetTaskPri((struct Task *) ProcessPtr, NewPri);
else
{ printf("Worm Wars: Priority range is -5 to +5\n", argv[0]);
cleanexit(EXIT_FAILURE);
} }
else
{ argument = TRUE;
pathname = argv[i];
}
enginesetup();
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37L)))
{ printf("Worm Wars: You need Kickstart R2.04+!\n(Can't open intuition.library V37+!)\n");
cleanexit(EXIT_FAILURE);
}
if (SysBase->lib_Version < 36L)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Need exec.library V36+!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open graphics.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 37L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open GadTools.library V37+!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open ASL.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(InputPortPtr = (struct MsgPort *) CreateMsgPort()))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open input.device!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(InputRqPtr = (struct IOStdReq *) CreateIORequest(InputPortPtr, sizeof(struct IOStdReq))))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create input I/O request!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (InputClosed = OpenDevice("input.device", 0, InputRqPtr, 0))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open input.device!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(StartValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
{ DisplayAlert(AT_Recovery, ALERTTIMERVALUE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(CurrentValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
{ DisplayAlert(AT_Recovery, ALERTTIMERVALUE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(PausedValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
{ DisplayAlert(AT_Recovery, ALERTTIMERVALUE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(TimerPortPtr = (struct MsgPort *) CreateMsgPort()))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't allocate timer message port!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(TimerRqPtr = (struct timerequest *) CreateIORequest(TimerPortPtr, sizeof(struct timerequest))))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create timer I/O request!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (TimerClosed = OpenDevice(TIMERNAME, UNIT_VBLANK, TimerRqPtr, 0))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open timer.device!\0", 24);
cleanexit(EXIT_FAILURE);
}
TimerBase = (struct Library *) TimerRqPtr->tr_node.io_Device;
/* PREPARE DISPLAY -----------------------------------------------
screen */
if (!(ScreenPtr = (struct Screen *) OpenScreenTags(NULL,
SA_Width, 640,
SA_Height, 256,
SA_Depth, 4,
SA_DisplayID, HIRES_KEY | PAL_MONITOR_ID,
SA_Title, TITLEBAR,
SA_Colors, Colours,
SA_Font, &Topaz8,
SA_Pens, Pens,
TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open screen!\0", 24);
cleanexit(EXIT_FAILURE);
}
// GadTools
if (!(CycleGadget.ng_VisualInfo = StringGadget.ng_VisualInfo = VisualInfoPtr = (APTR) GetVisualInfo(ScreenPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't get GadTools visual info!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
{ DisplayAlert(AT_Recovery, ALERTMENUCREATE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't lay out menus!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(PrevGadgetPtr = (struct Gadget *) CreateContext(&GListPtr)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create GadTools context!\0", 24);
cleanexit(EXIT_FAILURE);
}
for (player = 0; player <= 3; player++)
{ CycleGadget.ng_TopEdge = 184 + (player * (FONTX + 8));
CycleGadget.ng_GadgetText = GadgetText[player];
CycleGadgetPtr[player] = PrevGadgetPtr = (struct Gadget *) CreateGadget(CYCLE_KIND, PrevGadgetPtr, &CycleGadget, GTCY_Labels, GadgetOptions[player], GT_Underscore, '_', GTCY_Active, worm[player].control, TAG_DONE);
}
if (!PrevGadgetPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create cycle gadgets!\0", 24);
cleanexit(EXIT_FAILURE);
}
// main window
if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Top, 11,
WA_Width, SCREENXPIXEL,
WA_Height, SCREENYPIXEL,
WA_IDCMP, IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS | IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MENUPICK | IDCMP_MENUVERIFY | CYCLEIDCMP | STRINGIDCMP | IDCMP_REFRESHWINDOW | IDCMP_INTUITICKS,
WA_Gadgets, GListPtr,
WA_CustomScreen, ScreenPtr,
WA_Borderless, TRUE,
WA_Activate, TRUE,
WA_SmartRefresh, TRUE,
WA_RptQueue, 16,
TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open main window!\0", 24);
cleanexit(EXIT_FAILURE);
}
// redirection of AmigaDOS system requesters
OldWindowPtr = ProcessPtr->pr_WindowPtr;
ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, PATTERN, ASL_Window, MainWindowPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create ASL request!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* String gadgets: first the window is opened with the cycle gadgets.
It is necessary not to display the string gadgets yet, so the
gadgets are then created and added to the gadget list. You will note
there is no command given to render them as yet. When the attributes
are modified at highscore time, the applicable gadget is refreshed
then. */
for (which = 0; which <= HISCORES; which++)
{ StringGadget.ng_TopEdge = 104 + (which * HISCOREDISTANCE);
StringGadgetPtr[which] = PrevGadgetPtr = (struct Gadget *) CreateGadget(STRING_KIND, PrevGadgetPtr, &StringGadget, GTST_MaxChars, NAMELENGTH, STRINGA_ReplaceMode, TRUE, GA_Disabled, TRUE, TAG_DONE);
}
if (!PrevGadgetPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create string gadgets!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(JoyPortPtr = (struct MsgPort *) CreateMsgPort()))
{ say("Can't create joystick message port!", BLUE);
anykey(TRUE);
} else if (!(JoyRqPtr = (struct IOStdReq *) CreateIORequest(JoyPortPtr, sizeof(struct IOStdReq))))
{ say("Can't create joystick I/O request!", BLUE);
anykey(TRUE);
} else if (JoyClosed = OpenDevice("gameport.device", 1, JoyRqPtr, 0))
{ say("Can't open gameport.device!", BLUE);
anykey(TRUE);
} else
{ Forbid();
JoyRqPtr->io_Command = GPD_ASKCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Flags = IOF_QUICK;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
if (Controller == GPCT_NOCONTROLLER)
{ Controller = GPCT_ABSJOYSTICK;
JoyRqPtr->io_Command = GPD_SETCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
success = TRUE;
}
Permit();
if (success)
{ JoyRqPtr->io_Command = GPD_SETTRIGGER;
JoyRqPtr->io_Data = (APTR) &Trigger;
JoyRqPtr->io_Length = sizeof(struct GamePortTrigger);
DoIO(JoyRqPtr);
sendreadrequest();
joy = TRUE;
} else
/* Note that say(), anykey() calls must be outside the
Forbid()/Permit() pair. */
{ say("Gameport already in use!", BLUE);
anykey(TRUE);
} }
if (!(MEDPlayerBase = (struct MEDPlayerBase *) OpenLibrary("medplayer.library", 0L)))
{ say("Can't open MEDPlayer.library!", RED);
anykey(TRUE);
} else
{ say("Loading music...", WHITE);
if (SongPtr = (struct MMD0 *) LoadModule(MEDMODULE))
musicable = TRUE;
else
{ say("Can't load music!", RED);
anykey(TRUE);
} }
fxable = TRUE;
for (which = 0; which <= SAMPLES; which++)
sbase[which] = NULL;
say("Loading sound effects...", WHITE);
for (counter = 0; counter <= SAMPLES; counter++)
{ sbase[counter] = (UBYTE *) AllocMem(ssize[counter], MEMF_CHIP | MEMF_CLEAR);
if (!(FilePtr = (struct FileHandle *) Open(samp[counter].fname, MODE_OLDFILE)))
code = 1; // can't open file
else
{ rd8count = Read((BPTR) FilePtr, iobuffer, 8L);
if (rd8count == -1)
code = 2; // can't read file
else if (rd8count < 8)
code = 3; // not an IFF 8SVX; too short
else
{ p8Chunk = (struct Chunk *) iobuffer;
if (p8Chunk->ckID != ID_FORM)
code = 4; // not an IFF FORM
else if (!(fbase = (UBYTE *) AllocMem(fsize = p8Chunk->ckSize, MEMF_PUBLIC | MEMF_CLEAR)))
code = 5; // no memory for read
else
{ p8data = fbase;
rd8count = Read((BPTR) FilePtr, p8data, p8Chunk->ckSize);
if (rd8count == -1)
code = 6; // read error
else if (rd8count < p8Chunk->ckSize)
code = 7; // malformed IFF; too short
else if (MAKE_ID(*p8data, *(p8data + 1), *(p8data + 2), *(p8data + 3)) != ID_8SVX)
code = 8; // not an IFF 8SVX
else
{ p8data = p8data + 4;
while (p8data < fbase + fsize)
{ p8Chunk = (struct Chunk *) p8data;
switch(p8Chunk->ckID) {
case ID_VHDR:
pVoice8Header = (Voice8Header *) (p8data + 8L);
break;
case ID_BODY:
psample[0] = (SBYTE *) (p8data + 8L);
psample[1] = psample[0] + pVoice8Header->oneShotHiSamples;
length[counter][0] = (ULONG) pVoice8Header->oneShotHiSamples;
length[counter][1] = (ULONG) pVoice8Header->repeatHiSamples;
/* To grab the volume level from the IFF 8SVX file, instead
of from the header, add the following line here:
samp[counter].volume = (SBYTE) (pVoice8Header->volume / 156); */
break;
default:
break;
}
p8data += 8L + p8Chunk->ckSize;
if (p8Chunk->ckSize & 1L == 1)
p8data++;
}
if (length[counter][0] == 0)
yes[counter] = 1;
else yes[counter] = 0;
if (length[counter][yes[counter]] <= 102400)
ssize[counter] = length[counter][yes[counter]];
else ssize[counter] = 102400;
sbase[counter] = (UBYTE *) AllocMem(ssize[counter], MEMF_CHIP | MEMF_CLEAR);
if (!sbase[counter])
code = 9; // no chip memory
else
{ CopyMem(psample[yes[counter]], sbase[counter], ssize[counter]);
psample[yes[counter]] += ssize[counter];
speed[counter] = PALCLOCK / pVoice8Header->samplesPerSec;
if (fbase)
{ FreeMem(fbase, fsize);
fbase = NULL;
}
if (FilePtr)
{ Close((BPTR) FilePtr);
FilePtr = NULL;
} } } } } }
if (code)
{ freefx();
fxable = FALSE;
strcpy(errormessage, samp[counter].fname);
strcat(errormessage, ": ");
strcat(errormessage, sfxerror[code]);
say(errormessage, RED);
anykey(TRUE);
break;
} }
if (fxable)
toggle(F);
if (argument && !loadfields(pathname))
{ strcpy(errormessage, "Can't open ");
strcat(errormessage, pathname);
strcat(errormessage, "!");
say(errormessage, RED);
anykey(TRUE);
argument = FALSE;
pathname = DEFAULTSET;
}
if (!argument && !loadfields(DEFAULTSET))
{ strcpy(errormessage, "Can't open ");
strcat(errormessage, DEFAULTSET);
strcat(errormessage, "!");
say(errormessage, RED);
anykey(TRUE);
newfields();
}
while (1)
{ titlescreen();
// MAIN GAME LOOP -------------------------------------------------
while (a == PLAYGAME)
{ if (!(++r % VERYSLOW))
{ GetSysTime(CurrentValPtr);
SubTime(CurrentValPtr, StartValPtr);
secondsleft = secondsperlevel - CurrentValPtr->tv_secs;
timeloop();
}
TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = delay;
SendIO(TimerRqPtr);
gameloop();
if (CheckIO(TimerRqPtr))
draw(CLOCKICON, ICONY, CLOCK);
else
{ blitmode(BLACK);
draw(CLOCKICON, ICONY, ANYTHING);
blitmode(NORMAL);
}
WaitIO(TimerRqPtr);
}
say("Title Screen", WHITE);
}
}
// SUPPORT FUNCTIONS -----------------------------------------------------
void activate(SBYTE which)
{ struct InputEvent InputEvent;
struct IEPointerPixel NewPixel;
NewPixel.iepp_Screen = (struct Screen *) ScreenPtr;
NewPixel.iepp_Position.X = 472;
NewPixel.iepp_Position.Y = 121 + (which * HISCOREDISTANCE);
InputEvent.ie_EventAddress = (APTR) &NewPixel;
InputEvent.ie_NextEvent = NULL;
InputEvent.ie_Class = IECLASS_NEWPOINTERPOS;
InputEvent.ie_SubClass = IESUBCLASS_PIXEL;
InputEvent.ie_Code = IECODE_NOBUTTON;
InputEvent.ie_Qualifier = NULL;
InputRqPtr->io_Data = (APTR) &InputEvent;
InputRqPtr->io_Length = sizeof (struct InputEvent);
InputRqPtr->io_Command = IND_WRITEEVENT;
DoIO((struct IORequest *) InputRqPtr);
NewPixel.iepp_Screen = (struct Screen *) ScreenPtr;
InputEvent.ie_NextEvent = NULL;
InputEvent.ie_Class = IECLASS_RAWKEY;
InputEvent.ie_Code = 0x00;
InputEvent.ie_Qualifier = IEQUALIFIER_LCOMMAND + IEQUALIFIER_LALT;
InputRqPtr->io_Data = (APTR) &InputEvent;
InputRqPtr->io_Length = sizeof (struct InputEvent);
InputRqPtr->io_Command = IND_WRITEEVENT;
DoIO((struct IORequest *) InputRqPtr);
NewPixel.iepp_Screen = (struct Screen *) ScreenPtr;
InputEvent.ie_NextEvent = NULL;
InputEvent.ie_Class = IECLASS_RAWMOUSE;
InputEvent.ie_Code = 0x00 + IECODE_UP_PREFIX;
InputEvent.ie_Qualifier = NULL;
InputRqPtr->io_Data = (APTR) &InputEvent;
InputRqPtr->io_Length = sizeof (struct InputEvent);
InputRqPtr->io_Command = IND_WRITEEVENT;
DoIO((struct IORequest *) InputRqPtr);
}
/* NAME anykey -- wait for a user press
SYNOPSIS anykey(ABOOL);
FUNCTION Waits for a keypress, mousebutton press, or (optionally)
times out after a few seconds.
INPUTS timeout - whether to timeout automatically after a few
seconds
RESULTS FALSE if user presses Escape, TRUE otherwise.
FILE system.c */
ABOOL anykey(ABOOL timeout)
{ ABOOL done = FALSE;
SBYTE count = 0;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
clearkybd();
Forbid();
MainWindowPtr->Flags = WFLG_BORDERLESS | WFLG_ACTIVATE | WFLG_RMBTRAP;
Permit();
while (!done)
{ if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
done = TRUE;
sendreadrequest();
}
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
if (class == IDCMP_RAWKEY)
{ if ((!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
{ done = TRUE;
if (code == M)
toggle(M);
else if (code == F)
toggle(F);
else if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else return(FALSE);
} } }
else if (class == IDCMP_CLOSEWINDOW)
cleanexit(EXIT_SUCCESS);
else if (class == IDCMP_ACTIVEWINDOW)
ignore = TRUE;
else if (class == IDCMP_MOUSEBUTTONS && !(qual & IEQUALIFIER_REPEAT))
{ if (ignore)
{ if (code == SELECTUP)
ignore = FALSE;
} else if (code == SELECTDOWN || code == MENUDOWN)
done = TRUE;
} else if (class == IDCMP_INTUITICKS && timeout && ++count > PATIENCE)
done = TRUE;
} }
Forbid();
MainWindowPtr->Flags = WFLG_BORDERLESS | WFLG_ACTIVATE;
Permit();
return(TRUE);
}
void blitmode(SBYTE state)
{ if (state == BLACK)
{ Image.PlanePick = 0x0;
Image.PlaneOnOff = 0x0;
}
else if (state == WHITE)
{ Image.PlanePick = 0x0;
Image.PlaneOnOff = 0x1;
}
else
Image.PlanePick = 0xf;
}
void celebrate(void)
{ ABOOL done = FALSE;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
waitasec();
clearkybd();
while (done == FALSE)
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch (class)
{
case IDCMP_RAWKEY:
if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
done = TRUE;
}
else if (code == RETURN || code == ENTER || code == SPACEBAR)
done = TRUE;
else if (code == M)
toggle(M);
else if (code == F)
toggle(F);
break;
case IDCMP_MOUSEBUTTONS:
if (!(qual & IEQUALIFIER_REPEAT))
{ if (ignore)
{ if (code == SELECTUP)
ignore = FALSE;
} else if (code == SELECTDOWN)
done = TRUE;
} break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
default:
break;
} }
if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
done = TRUE;
sendreadrequest();
}
SetRGB4(&ScreenPtr->ViewPort, 17, rand() % 16, rand() % 16, rand() % 16);
draw(rand() % (FIELDX + 1), rand() % (FIELDY + 1), rand() % LASTOBJECT);
}
SetRGB4(&ScreenPtr->ViewPort, 17, 14, 4, 4);
a = GAMEOVER;
}
void cleanexit(SLONG rc)
{ SBYTE index;
if (TimerRqPtr && (!CheckIO(TimerRqPtr)))
{ AbortIO(TimerRqPtr);
WaitIO(TimerRqPtr); }
if (menu) ClearMenuStrip();
if (mode == FX) { freefx();
for (index = 0; index <= SAMPLES; index++)
if (sbase[index])
FreeMem(sbase[index], ssize[index]); }
if (mode == MUSIC) StopPlayer();
if (SongPtr) UnLoadModule(SongPtr);
if (mode == MUSIC) FreePlayer();
if (MEDPlayerBase) CloseLibrary(MEDPlayerBase);
if (joy) { AbortIO(JoyRqPtr);
WaitIO(JoyRqPtr); }
if (Controller != GPCT_NOCONTROLLER)
{ Forbid();
Controller = GPCT_NOCONTROLLER;
JoyRqPtr->io_Command = GPD_SETCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
Permit(); }
if (!JoyClosed) CloseDevice(JoyRqPtr);
if (JoyRqPtr) DeleteIORequest(JoyRqPtr);
if (JoyPortPtr) DeleteMsgPort(JoyPortPtr);
if (ASLRqPtr) FreeAslRequest(ASLRqPtr);
if (OldWindowPtr) ProcessPtr->pr_WindowPtr = OldWindowPtr;
if (MainWindowPtr) { clearkybd();
CloseWindow(MainWindowPtr); }
if (GListPtr) FreeGadgets(GListPtr);
if (MenuPtr) FreeMenus(MenuPtr);
if (VisualInfoPtr) FreeVisualInfo(VisualInfoPtr);
if (ScreenPtr) CloseScreen(ScreenPtr);
if (!TimerClosed) CloseDevice(TimerRqPtr);
if (TimerRqPtr) DeleteIORequest(TimerRqPtr);
if (TimerPortPtr) DeleteMsgPort(TimerPortPtr);
if (PausedValPtr) FreeMem(PausedValPtr, sizeof(struct timeval));
if (CurrentValPtr) FreeMem(CurrentValPtr, sizeof(struct timeval));
if (StartValPtr) FreeMem(StartValPtr, sizeof(struct timeval));
if (!InputClosed) CloseDevice(InputRqPtr);
if (InputRqPtr) DeleteIORequest(InputRqPtr);
if (InputPortPtr) DeleteMsgPort(InputPortPtr);
if (ASLBase) CloseLibrary(ASLBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) { OpenWorkBench();
CloseLibrary(IntuitionBase); }
SetTaskPri((struct Task *) ProcessPtr, OldPri);
exit(rc); // End of program.
}
void clearjoystick(void)
{ if (joy)
while (GetMsg(JoyPortPtr))
sendreadrequest();
}
void clearkybd(void)
{ struct IntuiMessage* MsgPtr;
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
GT_ReplyIMsg(MsgPtr);
}
void clearstats(void)
{ SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, 0, STARTYPIXEL, STARTXPIXEL - 1, ENDYPIXEL);
RectFill(MainWindowPtr->RPort, ENDXPIXEL + 1, STARTYPIXEL, SCREENXPIXEL, SCREENYPIXEL);
if (mode == MUSIC)
draw(MUSICICON, ICONY, MUSIC);
else if (mode == FX)
draw(MUSICICON, ICONY, FX);
if (sticky)
draw(STICKYICON, ICONY, STICKY);
}
void draw(SBYTE x, SBYTE y, SBYTE image)
{ Image.ImageData = ImageData[image];
DrawImage(MainWindowPtr->RPort, &Image, (x * SQUAREX) + STARTXPIXEL, (y * SQUAREY) + STARTYPIXEL);
}
ULONG effect(SBYTE index)
{ SBYTE i;
SBYTE ok = -1;
ULONG oldestreceipt = (ULONG) -1L;
PERSIST ULONG receipt = 1L;
/* oldestreceipt = temporary variable for ascertaining oldest
sound still playing.
receipt = next unused receipt number (monotonically incrementing). */
if (mode == FX)
{ for (i = 0; i <= 3; i++)
{ // decide on a channel
if (ok == -1)
{ if (!eversent[i])
ok = i;
else if (CheckIO(AudioRqPtr[i]))
{ WaitIO(AudioRqPtr[i]);
ok = i;
} } }
if (ok == -1)
{ for (i = 0; i <= 3; i++)
if (receipter[i] < oldestreceipt)
{ ok = i;
oldestreceipt = receipter[i];
}
AbortIO(AudioRqPtr[ok]);
WaitIO(AudioRqPtr[ok]);
}
eversent[ok] = TRUE;
if (samp[index].repeat)
AudioRqPtr[ok]->ioa_Cycles = 0;
else
AudioRqPtr[ok]->ioa_Cycles = 1;
AudioRqPtr[ok]->ioa_Request.io_Command = CMD_WRITE;
AudioRqPtr[ok]->ioa_Request.io_Flags = ADIOF_PERVOL;
AudioRqPtr[ok]->ioa_Request.io_Unit = (1 << ok);
AudioRqPtr[ok]->ioa_Volume = samp[index].volume;
AudioRqPtr[ok]->ioa_Period = (UWORD) speed[index];
AudioRqPtr[ok]->ioa_Request.io_Message.mn_ReplyPort
= AudioPortPtr[ok];
AudioRqPtr[ok]->ioa_Data = (UBYTE *) sbase[index];
AudioRqPtr[ok]->ioa_Length = length[index][yes[index]];
BeginIO(AudioRqPtr[ok]);
receipter[ok] = receipt;
return(receipt++);
} }
void fieldedit(void)
{ UBYTE oldbrush = ANYTHING, stamp;
SBYTE deltax = 0, deltay = 0, lastx, lasty, pointerx, pointery, which, x, y;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
ABOOL leftdown = FALSE, rightdown = FALSE, timer = FALSE;
ClearMenuStrip(MenuPtr);
menu = FALSE;
NewMenu[TOOLSSTART + 1 + IN_TS].nm_Flags = CHECKIT | MENUTOGGLE;
NewMenu[TOOLSSTART + 1 + IN_FE].nm_Flags = CHECKIT | MENUTOGGLE | CHECKED | NM_ITEMDISABLED;
NewMenu[LEVELSTART].nm_Flags = 0;
if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
{ DisplayAlert(AT_Recovery, ALERTMENUCREATE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, ALERTMENULAYOUT, 24);
if (modified)
savefields(EMERGENCYNAME);
cleanexit(EXIT_FAILURE);
}
SetMenuStrip(MainWindowPtr, MenuPtr);
menu = TRUE;
say("Field Editor", WHITE);
setpointer(brush);
if (level > levels)
level = levels;
// draw pseudo-gadgets
clearstats();
for (which = 0; which <= 7; which++)
DrawBevelBox(MainWindowPtr->RPort, STARTXPIXEL - 5 - (SQUAREX * 3), 46 + STARTYPIXEL + (which * SQUAREY * 3), SQUAREX + 9, SQUAREY + 4, GT_VisualInfo, VisualInfoPtr);
SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( GOLDGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F1:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (SILVERGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F2:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( EMPTYGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F3:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( WOODGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F4:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( STONEGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F5:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( ONEGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F6:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( TWOGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F7:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( STARTGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F8:", 3);
draw(GADGETX, GOLDGADGET, GOLD);
draw(GADGETX, SILVERGADGET, SILVER);
draw(GADGETX, EMPTYGADGET, EMPTY);
draw(GADGETX, WOODGADGET, WOOD);
draw(GADGETX, STONEGADGET, STONE);
draw(GADGETX, ONEGADGET, ONE);
draw(GADGETX, TWOGADGET, TWO);
draw(GADGETX, STARTGADGET, START);
underline(brush);
renderboard();
saylevel(WHITE);
clearkybd();
x = lastx = startx[level];
y = lasty = starty[level];
while (a == FIELDEDIT)
{ stamp = NOSQUARE;
if (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
if (class == IDCMP_MENUVERIFY && MsgPtr->MouseX >= STARTXPIXEL && MsgPtr->MouseX <= ENDXPIXEL && MsgPtr->MouseY >= STARTYPIXEL && MsgPtr->MouseY <= ENDYPIXEL)
{ MsgPtr->Code = MENUCANCEL;
oldbrush = brush;
brush = EMPTY;
rightdown = TRUE;
}
ReplyMsg(MsgPtr);
switch (class)
{
case IDCMP_MENUPICK:
if (code != MENUNULL)
{ switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
effect(FXFILENEW);
newfields();
say("New done.", WHITE);
break;
case IN_OPEN:
effect(FXFILEOPEN);
fileopen();
break;
case IN_SAVE:
effect(FXFILESAVE);
filesaveas(FALSE);
break;
case IN_SAVEAS:
effect(FXFILESAVEAS);
filesaveas(TRUE);
break;
case IN_ABOUT:
fileabout();
break;
case IN_QUIT:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
default:
break;
}
break;
case MN_TOOLS:
a = GAMEOVER;
break;
case MN_LEVEL:
switch (ITEMNUM(code))
{
case IN_INSERT:
levelinsert();
break;
case IN_DELETE:
leveldelete();
break;
case IN_ERASE:
levelerase();
break;
case IN_APPEND:
levelappend();
break;
default:
break;
}
break;
default:
break;
} }
break;
case IDCMP_RAWKEY:
lastx = x;
lasty = y;
switch(code)
{
case DELETE:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
level = 1;
else if (--level < 0)
level = levels;
saylevel(WHITE);
renderboard();
}
break;
case HELP:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
level = levels;
else if (++level > levels)
level = 0;
saylevel(WHITE);
renderboard();
}
break;
case M:
if (!(qual & IEQUALIFIER_REPEAT))
toggle(M);
break;
case F:
if (!(qual & IEQUALIFIER_REPEAT))
toggle(F);
break;
case ESCAPE:
if (!(qual & IEQUALIFIER_REPEAT))
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else a = GAMEOVER;
break;
case SPACEBAR:
case RETURN:
case ENTER:
if (!(qual & IEQUALIFIER_REPEAT))
a = GAMEOVER;
break;
case N:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXFILENEW);
newfields();
say("New done.", WHITE);
}
break;
case O:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXFILEOPEN);
fileopen();
}
break;
case S:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXFILESAVE);
filesaveas(FALSE);
}
break;
case A:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXFILESAVEAS);
filesaveas(TRUE);
}
break;
case Q:
if (!(qual & IEQUALIFIER_REPEAT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
}
break;
case NUMERICOPEN:
effect(FXCLICK);
setpointer(NORMAL);
underline(-1);
if (brush-- == 0 || brush > LASTOBJECT)
brush = LASTOBJECT;
stamp = brush;
break;
case NUMERICCLOSE:
effect(FXCLICK);
setpointer(NORMAL);
underline(-1);
if (++brush > LASTOBJECT)
brush = 0;
stamp = brush;
break;
case I:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
levelinsert();
break;
case D:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
leveldelete();
break;
case E:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
levelerase();
break;
case K:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
levelappend();
break;
case ALPHAONE:
effect(FXCLICK);
stamp = GOLD;
break;
case ALPHATWO:
effect(FXCLICK);
stamp = SILVER;
break;
case ALPHATHREE:
effect(FXCLICK);
stamp = EMPTY;
break;
case ALPHAFOUR:
effect(FXCLICK);
stamp = WOOD;
break;
case ALPHAFIVE:
effect(FXCLICK);
stamp = STONE;
break;
case ALPHASIX:
effect(FXCLICK);
stamp = ONE;
break;
case ALPHASEVEN:
effect(FXCLICK);
stamp = TWO;
break;
case ALPHAEIGHT:
effect(FXCLICK);
stamp = START;
break;
case F1:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(GOLD);
else setbrush(GOLD);
}
break;
case F2:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(SILVER);
else setbrush(SILVER);
}
break;
case F3:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(EMPTY);
else setbrush(EMPTY);
}
break;
case F4:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(WOOD);
else setbrush(WOOD);
}
break;
case F5:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(STONE);
else setbrush(STONE);
}
break;
case F6:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(ONE);
}
break;
case F7:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(TWO);
}
break;
case F8:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(START);
}
break;
case NUMERICZERO:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
{ if (!sticky)
{ sticky = TRUE;
draw(STICKYICON, ICONY, STICKY);
stamp = brush;
} else
{ sticky = FALSE;
blitmode(BLACK);
draw(STICKYICON, ICONY, ANYTHING);
blitmode(NORMAL);
} }
break;
case NUMERICDOT:
effect(FXCLICK);
if (!(qual & IEQUALIFIER_REPEAT))
stamp = brush;
break;
case NUMERICFOUR:
case LEFT:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
x = 0;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
x = xwrap(x - ALTJUMP);
else
x = xwrap(x - 1);
if (sticky)
stamp = brush;
break;
case NUMERICSIX:
case RIGHT:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
x = FIELDX;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
x = xwrap(x + ALTJUMP);
else
x = xwrap(x + 1);
if (sticky)
stamp = brush;
break;
case NUMERICEIGHT:
case UP:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
y = 0;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
y = ywrap(y - ALTJUMP);
else
y = ywrap(y - 1);
if (sticky)
stamp = brush;
break;
case NUMERICFIVE:
case NUMERICTWO:
case DOWN:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
y = FIELDY;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
y = ywrap(y + ALTJUMP);
else
y = ywrap(y + 1);
if (sticky)
stamp = brush;
break;
case NUMERICSEVEN:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = 0;
y = 0;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x - ALTJUMP);
y = ywrap(y - ALTJUMP);
} else
{ x = xwrap(x - 1);
y = ywrap(y - 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICNINE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = FIELDX;
y = 0;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x + ALTJUMP);
y = ywrap(y - ALTJUMP);
} else
{ x = xwrap(x + 1);
y = ywrap(y - 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICONE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = 0;
y = FIELDY;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x - ALTJUMP);
y = ywrap(y + ALTJUMP);
} else
{ x = xwrap(x - 1);
y = ywrap(y + 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICTHREE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = FIELDX;
y = FIELDY;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x + ALTJUMP);
y = ywrap(y + ALTJUMP);
} else
{ x = xwrap(x + 1);
y = ywrap(y + 1);
}
if (sticky)
stamp = brush;
break;
default:
break;
}
if (x != lastx || y != lasty)
{ updatesquare(lastx, lasty);
if (stamp == NOSQUARE)
{ blitmode(WHITE);
draw(x, y, ANYTHING);
blitmode(NORMAL);
} }
break;
case IDCMP_MOUSEBUTTONS:
updatesquare(x, y);
switch (code)
{
case SELECTUP:
if (ignore)
ignore = FALSE;
else leftdown = FALSE;
break;
case SELECTDOWN:
if (!ignore)
{ effect(FXCLICK);
leftdown = TRUE;
}
break;
case MENUUP:
rightdown = FALSE;
brush = oldbrush;
oldbrush = ANYTHING;
break;
default:
// MENUDOWN
break;
}
break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
default:
// IDCMP_MENUVERIFY, IDCMP_INTUITICKS
break;
} }
else if (joy)
{ if (GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
stamp = brush;
deltax = (SBYTE) GameEvent.ie_position.ie_xy.ie_x;
deltay = (SBYTE) GameEvent.ie_position.ie_xy.ie_y;
if (GameEvent.ie_Qualifier == IEQUALIFIER_LEFTBUTTON)
stamp = brush;
sendreadrequest();
}
if (deltax || deltay)
{ if (!timer)
{ TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = JOYDELAY;
SendIO(TimerRqPtr);
timer = TRUE;
} else if (CheckIO(TimerRqPtr))
{ lastx = x;
lasty = y;
x = xwrap(x + deltax);
y = ywrap(y + deltay);
updatesquare(lastx, lasty);
if (stamp == NOSQUARE)
{ blitmode(WHITE);
draw(x, y, ANYTHING);
blitmode(NORMAL);
}
timer = FALSE;
} } }
if (leftdown || rightdown)
{ pointerx = xpixeltosquare(MainWindowPtr->MouseX);
pointery = ypixeltosquare(MainWindowPtr->MouseY);
if (valid(pointerx, pointery))
{ x = pointerx;
y = pointery;
stamp = brush;
updatesquare(lastx, lasty);
}
else if (leftdown && pointerx == GADGETX &&
(pointery == GOLDGADGET || pointery == SILVERGADGET || pointery == EMPTYGADGET || pointery == WOODGADGET || pointery == STONEGADGET || pointery == ONEGADGET || pointery == TWOGADGET || pointery == STARTGADGET))
{ switch (pointery)
{
case GOLDGADGET:
setbrush(GOLD);
break;
case SILVERGADGET:
setbrush(SILVER);
break;
case EMPTYGADGET:
setbrush(EMPTY);
break;
case WOODGADGET:
setbrush(WOOD);
break;
case STONEGADGET:
setbrush(STONE);
break;
case ONEGADGET:
setbrush(ONE);
break;
case TWOGADGET:
setbrush(TWO);
break;
case STARTGADGET:
setbrush(START);
break;
default:
break;
} } }
if (stamp != NOSQUARE)
{ if (stamp == START && board[level][x][y] != TELEPORT)
{ if (x != startx[level] || y != starty[level])
{ draw(startx[level], starty[level], EMPTY);
board[level][startx[level]][starty[level]] = EMPTY;
draw(x, y, START);
startx[level] = x;
starty[level] = y;
modified = TRUE;
clearthem = TRUE;
} }
else if (x != startx[level] || y != starty[level])
{ if (stamp == ONE || stamp == TWO)
{ if (teleport[level][partner(stamp - ONE)].alive == FALSE || x != teleport[level][partner(stamp - ONE)].x || y != teleport[level][partner(stamp - ONE)].y)
{ if (teleport[level][stamp - ONE].alive == TRUE)
{ draw(teleport[level][stamp - ONE].x, teleport[level][stamp - ONE].y, EMPTY);
board[level][teleport[level][stamp - ONE].x][teleport[level][stamp - ONE].y] = EMPTY;
} else
teleport[level][stamp - ONE].alive = TRUE;
board[level][x][y] = TELEPORT;
draw(x, y, stamp);
teleport[level][stamp - ONE].x = x;
teleport[level][stamp - ONE].y = y;
modified = TRUE;
clearthem = TRUE;
} }
else
{ if (board[level][x][y] == TELEPORT)
if (teleport[level][0].alive == TRUE && x == teleport[level][0].x && y == teleport[level][0].y)
teleport[level][0].alive = FALSE;
else teleport[level][1].alive = FALSE;
draw(x, y, stamp);
board[level][x][y] = stamp;
modified = TRUE;
clearthem = TRUE;
} } } }
// exit to title screen
if (timer)
{ AbortIO(TimerRqPtr);
WaitIO(TimerRqPtr);
timer = FALSE;
}
if (oldbrush != ANYTHING)
brush = oldbrush;
setpointer(NORMAL);
clearstats();
if (clearthem)
clearhiscores();
matchteleports();
ClearMenuStrip(MenuPtr);
menu = FALSE;
NewMenu[TOOLSSTART + 1 + IN_TS].nm_Flags = CHECKIT | MENUTOGGLE | CHECKED | NM_ITEMDISABLED;
NewMenu[TOOLSSTART + 1 + IN_FE].nm_Flags = CHECKIT | MENUTOGGLE;
NewMenu[LEVELSTART].nm_Flags = NM_MENUDISABLED;
if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
{ DisplayAlert(AT_Recovery, ALERTMENUCREATE, 24);
cleanexit(EXIT_FAILURE);
}
if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, ALERTMENULAYOUT, 24);
if (modified)
savefields(EMERGENCYNAME);
cleanexit(EXIT_FAILURE);
}
SetMenuStrip(MainWindowPtr, MenuPtr);
menu = TRUE;
}
void fileabout(void)
{ ABOOL done = FALSE;
SBYTE line;
UWORD code, qual;
ULONG class;
struct Window* AboutWindowPtr;
struct IntuiMessage* MsgPtr;
effect(FXFILEABOUT);
if (!(AboutWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - (ABOUTXPIXEL / 2),
WA_Top, (SCREENYPIXEL / 2) - (ABOUTYPIXEL / 2),
WA_Width, ABOUTXPIXEL,
WA_Height, ABOUTYPIXEL,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, "About Worm Wars",
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE)))
{ say("Can't open About... window!", RED);
anykey(TRUE);
} else
{ SetAPen(AboutWindowPtr->RPort, BLUE);
RectFill(AboutWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 11, ABOUTYPIXEL - 6);
SetAPen(AboutWindowPtr->RPort, ABOUTSHADOW);
Move(AboutWindowPtr->RPort, 7, ABOUTYPIXEL - 5);
Draw(AboutWindowPtr->RPort, 7, 12);
Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 10, 12);
SetAPen(AboutWindowPtr->RPort, ABOUTSHINE);
Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 10, ABOUTYPIXEL - 5);
Draw(AboutWindowPtr->RPort, 8, ABOUTYPIXEL - 5);
SetAPen(AboutWindowPtr->RPort, BLACK);
SetDrMd(AboutWindowPtr->RPort, JAM1);
for (line = 0; line <= ABOUTLINES; line++)
{ Move(AboutWindowPtr->RPort, about[line].x, about[line].y);
Text(AboutWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
}
DrawBevelBox(AboutWindowPtr->RPort, 18, 21, 49, 23, GT_VisualInfo, VisualInfoPtr);
DrawImage(AboutWindowPtr->RPort, &About, 20, 23);
while (!done)
{ while (MsgPtr = (struct IntuiMessage *) GetMsg(AboutWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_CLOSEWINDOW)
done = TRUE;
else if (class == IDCMP_RAWKEY)
{ if (code == SPACEBAR || code == RETURN || code == ENTER || code == HELP)
done = TRUE;
else if (code == ESCAPE)
if (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ if (verify())
{ CloseWindow(AboutWindowPtr);
cleanexit(EXIT_SUCCESS);
} }
else done = TRUE;
} } }
CloseWindow(AboutWindowPtr);
clearkybd();
} }
void fileopen(void)
{ TEXT temp1[81] = {"Opened "}, temp2[3], newpathname[255];
strcpy(newpathname, pathname);
if (AslRequestTags(ASLRqPtr, ASL_Hail, ASLOPENHAIL, ASL_FuncFlags, FILF_PATGAD, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
if (loadfields(newpathname))
{ strcpy(pathname, newpathname);
strcat(temp1, pathname);
strcat(temp1, " (");
stci_d(temp2, levels);
strcat(temp1, temp2);
strcat(temp1, " levels).");
say(temp1, WHITE);
if (a == FIELDEDIT)
renderboard();
else hiscores();
} else
{ strcpy(temp1, "Couldn't open ");
strcat(temp1, newpathname);
strcat(temp1, "!");
say(temp1, WHITE);
} }
if (a == GAMEOVER)
anykey(TRUE);
}
void filesaveas(ABOOL flag)
{ ABOOL cont = TRUE;
TEXT newpathname[255], temp1[SAYLIMIT + 1], temp2[3];
// flag is TRUE for 'save as...', FALSE for 'save'.
strcpy(newpathname, pathname);
if (flag)
if (AslRequestTags(ASLRqPtr, ASL_Hail, ASLSAVEHAIL, ASL_FuncFlags, FILF_PATGAD | FILF_SAVE, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
} else cont = FALSE;
if (cont)
{ strcpy(temp1, "Saving ");
strcat(temp1, pathname);
strcat(temp1, "...");
say(temp1, WHITE);
if (savefields(newpathname))
{ strcpy(pathname, newpathname);
strcpy(temp1, "Saved ");
strcat(temp1, pathname);
strcat(temp1, " (");
stci_d(temp2, levels);
strcat(temp1, temp2);
strcat(temp1, " levels).");
} else
{ strcpy(temp1, "Couldn't save ");
strcat(temp1, newpathname);
strcat(temp1, "!");
}
say(temp1, WHITE);
if (a == GAMEOVER)
anykey(TRUE);
} }
void freefx(void)
{ SBYTE i;
stopfx(0L);
if (!AudioClosed)
{ CloseDevice((struct IORequest *) AudioRqPtr[0]);
AudioClosed = TRUE;
}
for (i = 0; i <= 3; i++)
{ if (AudioRqPtr[i])
{ DeleteIORequest(AudioRqPtr[i]);
AudioRqPtr[i] = NULL;
}
if (AudioPortPtr[i])
{ DeleteMsgPort(AudioPortPtr[i]);
AudioPortPtr[i] = NULL;
} }
if (fbase)
{ FreeMem(fbase, fsize);
fbase = NULL;
}
if (FilePtr)
{ Close((BPTR) FilePtr);
FilePtr = NULL;
} }
void gameinput(void)
{ ABOOL done;
UWORD code, qual;
ULONG class, Signal;
PERSIST SBYTE joyy;
struct IntuiMessage* MsgPtr;
ULONG SignalMask = 1L << MainWindowPtr->UserPort->mp_SigBit;
SBYTE keyplayer, which;
for (which = 0; which <= NUMKEYS; which++)
key[which].down = FALSE;
/* human control
keyboard */
while (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_RAWKEY && !(qual & IEQUALIFIER_REPEAT) && code < KEYUP)
{ switch(code) {
case M:
toggle(M);
break;
case F:
toggle(F);
break;
case P:
clearkybd();
say("Paused...press P to unpause", WHITE);
GetSysTime(CurrentValPtr);
done = FALSE;
while (!done)
{ Signal = Wait(SignalMask);
if (Signal & SignalMask)
{ if (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_RAWKEY && (!(qual & IEQUALIFIER_REPEAT)))
{ if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
{ a = GAMEOVER;
worm[0].lives = 0;
worm[1].lives = 0;
worm[2].lives = 0;
worm[3].lives = 0;
done = TRUE;
} }
else if (code == M)
toggle(M);
else if (code == F)
toggle(F);
else if (code == P)
{ say("Unpaused", WHITE);
done = TRUE;
} } } } }
GetSysTime(PausedValPtr);
SubTime(PausedValPtr, CurrentValPtr);
AddTime(StartValPtr, PausedValPtr);
break;
case ESCAPE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
{ a = GAMEOVER;
worm[0].lives = worm[1].lives = worm[2].lives = worm[3].lives = 0;
}
break;
default:
for (which = 0; which <= NUMKEYS; which++)
if (code == key[which].scancode)
key[which].down = TRUE;
break;
} }
else if (class == IDCMP_CLOSEWINDOW)
cleanexit(EXIT_SUCCESS);
else if (class == IDCMP_REFRESHWINDOW)
{ GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
} }
/* other IDCMP messages we receive but ignore are: IDCMP_ACTIVEWINDOW,
IDCMP_MOUSEBUTTONS, IDCMP_INTUITICKS. */
for (which = 0; which <= NUMKEYS; which++)
{ if (key[which].down)
{ if (key[which].special == ONEHUMAN)
{ if (worm[0].control == HUMAN && worm[1].control != HUMAN)
queue(0, key[which].deltax, key[which].deltay);
else if (worm[0].control != HUMAN && worm[1].control == HUMAN)
queue(1, key[which].deltax, key[which].deltay);
} else if (key[which].special == MOVE || key[which].special == AMMO)
{ if (worm[key[which].player].control == HUMAN)
keyplayer = key[which].player;
else if (key[which].player == 1 && worm[0].control == HUMAN && worm[1].control != HUMAN)
keyplayer = 0;
else if (key[which].player == 0 && worm[1].control == HUMAN && worm[0].control != HUMAN)
keyplayer = 1;
else keyplayer = -1;
if (keyplayer != -1)
queue(keyplayer, key[which].deltax, key[which].deltay);
} else if (worm[1].lives > 0) // assumes key[which].special == TRAINER
train(key[which].scancode);
} }
// joysticks
if (worm[2].control == HUMAN)
while (GetMsg(JoyPortPtr))
{ if (GameEvent.ie_position.ie_xy.ie_x != 0 || GameEvent.ie_position.ie_xy.ie_y != 0)
if (ignorenextjoy && GameEvent.ie_position.ie_xy.ie_y == joyy)
ignorenextjoy = FALSE;
else
{ queue(2, GameEvent.ie_position.ie_xy.ie_x, GameEvent.ie_position.ie_xy.ie_y);
if (GameEvent.ie_position.ie_xy.ie_x == 1)
{ ignorenextjoy = TRUE;
joyy = GameEvent.ie_position.ie_xy.ie_y;
} }
if (GameEvent.ie_Code == IECODE_LBUTTON)
queue(2, 0, 0);
sendreadrequest();
}
}
void hiscores(void)
{ SBYTE which;
TEXT tempstring[NAMELENGTH + 1];
/* render hiscores
darkdarkdarkdarkdarkdarkdarkdarkdark
a a a a w
r r r r h
k k k k i
| | | | t
whitewhitewhitewhitewhitewhitewhitee */
SetDrMd(MainWindowPtr->RPort, JAM1);
for (which = 0; which <= HISCORES; which++)
{ if (hiscore[which].player == -1)
SetAPen(MainWindowPtr->RPort, LIGHTGREY);
else SetAPen(MainWindowPtr->RPort, worm[hiscore[which].player].colour);
RectFill(MainWindowPtr->RPort, 159, 105 + which * HISCOREDISTANCE, 481, 114 + which * HISCOREDISTANCE);
if (hiscore[which].player == 0)
SetAPen(MainWindowPtr->RPort, DARKGREEN);
else if (hiscore[which].player == 1)
SetAPen(MainWindowPtr->RPort, DARKRED);
else if (hiscore[which].player == 2)
SetAPen(MainWindowPtr->RPort, DARKBLUE);
else if (hiscore[which].player == 3)
SetAPen(MainWindowPtr->RPort, DARKYELLOW);
else SetAPen(MainWindowPtr->RPort, DARKGREY);
Move(MainWindowPtr->RPort, 158, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 158, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 482, 104 + which * HISCOREDISTANCE);
if (hiscore[which].player != -1)
{ // divider bars
Move(MainWindowPtr->RPort, 182, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 182, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 254, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 254, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 290, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 290, 114 + which * HISCOREDISTANCE);
}
SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, 159, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 482, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 482, 105 + which * HISCOREDISTANCE);
SetAPen(MainWindowPtr->RPort, BLACK);
if (hiscore[which].player != -1)
{ stci_d(tempstring, which + 1);
tempstring[1] = '.';
Move(MainWindowPtr->RPort, 161, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, hiscore[which].score);
align(tempstring, 7, ' ');
Move(MainWindowPtr->RPort, 193, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 7);
if (hiscore[which].level == -1)
strcpy(tempstring, "All");
else
{ stci_d(tempstring, hiscore[which].level);
align(tempstring, 3, ' ');
}
Move(MainWindowPtr->RPort, 261, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 3);
Move(MainWindowPtr->RPort, 296, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, hiscore[which].name, strlen(hiscore[which].name));
} }
SetDrMd(MainWindowPtr->RPort, JAM2);
}
void hiscorenames(void)
{
ULONG class;
ABOOL done;
SBYTE which;
struct IntuiMessage* MsgPtr;
for (which = 0; which <= HISCORES; which++)
if (hiscore[which].fresh)
{ GT_SetGadgetAttrs(StringGadgetPtr[which], MainWindowPtr, NULL, GA_Disabled, FALSE, GTST_String, worm[hiscore[which].player].name, TAG_DONE);
activate(which);
done = FALSE;
while (!done)
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
GT_ReplyIMsg(MsgPtr);
if (class == IDCMP_GADGETUP)
done = TRUE;
else if (class == IDCMP_MOUSEBUTTONS)
activate(which);
else if (class == IDCMP_REFRESHWINDOW)
{ GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
} } }
GT_SetGadgetAttrs(StringGadgetPtr[which], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
effect(FXHISCORE);
strcpy(hiscore[which].name, ((struct StringInfo *) (StringGadgetPtr[which]->SpecialInfo))->Buffer);
if (hiscore[which].name[0] >= 97 && hiscore[which].name[0] <= 123)
hiscore[which].name[0] -= 32;
strcpy(worm[hiscore[which].player].name, hiscore[which].name);
hiscore[which].fresh = FALSE;
hiscores();
} }
void initsound(void)
{ SBYTE i;
PERSIST UBYTE chan[] = {15};
ABOOL success = TRUE;
for (i = 0; i <= 3; i++)
{ eversent[i] = FALSE;
if (!(AudioPortPtr[i] = (struct MsgPort *) CreateMsgPort()))
{ freefx();
say("No port for effects!", RED);
anykey(TRUE);
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
success = FALSE;
break;
} else if (!(AudioRqPtr[i] = (struct IOAudio *) CreateIORequest(AudioPortPtr[i], sizeof(struct IOAudio))))
{ freefx();
say("No I/O memory for effects!", RED);
anykey(TRUE);
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
success = FALSE;
break;
} }
if (success)
{ AudioRqPtr[0]->ioa_Request.io_Message.mn_ReplyPort = AudioPortPtr[0];
AudioRqPtr[0]->ioa_Request.io_Message.mn_Node.ln_Pri = 127;
AudioRqPtr[0]->ioa_AllocKey = 0;
AudioRqPtr[0]->ioa_Data = chan;
AudioRqPtr[0]->ioa_Length = 1;
if (AudioClosed = OpenDevice(AUDIONAME, 0L, (struct IORequest *) AudioRqPtr[0], 0L))
{ freefx();
say("Can't allocate all channels for effects!", RED);
anykey(TRUE);
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
} else
{ for (i = 1; i <= 3; i++)
CopyMem(AudioRqPtr[0], AudioRqPtr[i], sizeof(struct IOAudio));
mode = FX;
draw(MUSICICON, ICONY, FX);
} } }
/* WormWars 4.1 .fset/.FST format for fieldset contents and high
score table (Amiga and IBM-PC), as follows:
header
TEXT[] "FSET 4.1" (NULL-terminated)
SBYTE levels;
high score table
for (slot = 0; slot <= HISCORES; slot++)
{ SBYTE hiscore[slot].player,
hiscore[slot].level;
SLONG hiscore[slot].score;
TEXT[] hiscore[slot].name (NULL-terminated)
}
level data
for (level = 0; level <= levels; level++)
{ SBYTE startx[level],
starty[level];
ABOOL teleport[level][0].alive;
SBYTE teleport[level][0].x,
teleport[level][0].y;
ABOOL teleport[level][1].alive;
SBYTE teleport[level][1].x,
teleport[level][1].y;
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
SBYTE board[level][x][y];
}
version string
TEXT[] "$VER: Worm Wars 4.1 (dd.mm.yy) $" (NULL-terminated) */
void resettime(void)
{ GetSysTime(StartValPtr);
}
void rundown(SBYTE player)
{ TEXT tempstring[6];
SBYTE x, y;
UWORD counter = 0;
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, STARTXPIXEL, STARTYPIXEL, ENDXPIXEL, ENDYPIXEL);
SetAPen(MainWindowPtr->RPort, worm[player].colour);
Image.ImageData = ImageData[TREASURE];
DrawImage(MainWindowPtr->RPort, &Image, 201, 103);
Move(MainWindowPtr->RPort, 218, 108);
Text(MainWindowPtr->RPort, "Level Bonus: ## x #00 =", 26);
stci_d(tempstring, worm[player].multi);
Move(MainWindowPtr->RPort, 218 + (FONTX * 21), 108);
Text(MainWindowPtr->RPort, tempstring, 1);
stci_d(tempstring, level - 1);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 218 + (FONTX * 16), 108);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, (level - 1) * 100 * worm[player].multi);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 218 + (FONTX * 27), 108);
Text(MainWindowPtr->RPort, tempstring, 5);
Image.ImageData = ImageData[CLOCK];
DrawImage(MainWindowPtr->RPort, &Image, 201, 111);
Move(MainWindowPtr->RPort, 226, 116);
Text(MainWindowPtr->RPort, "Time Bonus: ##:## x #0 =", 25);
stci_d(tempstring, worm[player].multi);
Move(MainWindowPtr->RPort, 226 + (FONTX * 21), 116);
Text(MainWindowPtr->RPort, tempstring, 1);
stci_d(tempstring, secondsleft / 60);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 12), 116);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, secondsleft % 60);
align(tempstring, 2, '0');
Move(MainWindowPtr->RPort, 226 + (FONTX * 15), 116);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, secondsleft * 10 * worm[player].multi);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 26), 116);
Text(MainWindowPtr->RPort, tempstring, 5);
Image.ImageData = ImageData[FIRSTTAIL + player];
DrawImage(MainWindowPtr->RPort, &Image, 201, 119);
Move(MainWindowPtr->RPort, 226, 124);
Text(MainWindowPtr->RPort, "Tail Bonus: #### x # =", 25);
stci_d(tempstring, worm[player].multi);
Move(MainWindowPtr->RPort, 226 + (FONTX * 22), 124);
Text(MainWindowPtr->RPort, tempstring, 1);
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
if (field[x][y] == FIRSTTAIL + player)
counter++;
stci_d(tempstring, counter);
align(tempstring, 4, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 13), 124);
Text(MainWindowPtr->RPort, tempstring, 4);
stci_d(tempstring, counter * worm[player].multi);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 26), 124);
Text(MainWindowPtr->RPort, tempstring, 5);
wormscore(player, ((level - 1) * 100) +
(secondsleft * 10) +
counter);
waitasec();
anykey(FALSE);
}
void say(STRPTR sentence, COLOUR colour)
{ PERSIST SBYTE length = 0;
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, (SCREENXPIXEL / 2) - ((length * FONTX) / 2), 1, (SCREENXPIXEL / 2) + (length * FONTX / 2), FONTY + 1);
SetAPen(MainWindowPtr->RPort, colour);
length = (SBYTE) strlen(sentence);
if (length > SAYLIMIT)
{ *(sentence + SAYLIMIT - 1) = *(sentence + SAYLIMIT - 2) = *(sentence + SAYLIMIT - 3) = '.';
length = SAYLIMIT;
}
Move(MainWindowPtr->RPort, (SCREENXPIXEL / 2) - (length * FONTX / 2), FONTY);
Text(MainWindowPtr->RPort, sentence, length);
}
void sendreadrequest(void)
{ JoyRqPtr->io_Command = GPD_READEVENT;
JoyRqPtr->io_Flags = NULL;
JoyRqPtr->io_Length = sizeof(struct InputEvent);
JoyRqPtr->io_Data = (APTR) &GameEvent;
SendIO(JoyRqPtr);
}
void setpointer(SBYTE pointer) {
switch (pointer) {
case GOLD:
SetRGB4(&ScreenPtr->ViewPort, 17, 10, 8, 3); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 8, 4, 2); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12, 2); // shine
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case SILVER:
SetRGB4(&ScreenPtr->ViewPort, 17, 10, 10, 10); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 6, 6, 6); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 15, 15, 15); // shine
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case EMPTY:
SetRGB4(&ScreenPtr->ViewPort, 17, 2, 2, 2); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 0, 0, 0); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 6, 6, 6); // shine
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case WOOD:
SetRGB4(&ScreenPtr->ViewPort, 17, 8, 4, 2); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 2, 2, 2); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 14, 8, 3); // shine
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case STONE:
SetRGB4(&ScreenPtr->ViewPort, 17, 0, 0, 0); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 2, 2, 2); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 6, 6, 6); // shine
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
default:
SetRGB4(&ScreenPtr->ViewPort, 17, 14, 4, 4); // fill
SetRGB4(&ScreenPtr->ViewPort, 18, 3, 3, 3); // shadow
SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12, 12); // shine
ClearPointer(MainWindowPtr);
break; }
}
void stat(SBYTE player, SBYTE line)
{ ABOOL print = TRUE;
SBYTE i, num[7];
strcpy(num, " "); // 6 spaces
switch (line) {
case SCORELINE:
do
{ worm[player].oldscore += (LIFEMODULO - (worm[player].oldscore % LIFEMODULO));
if (worm[player].score >= worm[player].oldscore)
{ worm[player].lives++;
stat(player, LIVESLINE);
}
} while (worm[player].score > worm[player].oldscore);
worm[player].oldscore = worm[player].score;
if (worm[player].multi > 1)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
if (worm[player].score > SCORELIMIT)
{ strcpy(num, "!YEAH!");
Move(MainWindowPtr->RPort, (FONTX * 2) + (worm[player].statx * (ENDXPIXEL + FONTX)), STARTYPIXEL + 6 + (line * FONTY) + (worm[player].staty * (ENDYPIXEL - ((LINES + 2) * FONTY))));
Text(MainWindowPtr->RPort, num, 6);
if (level <= levels)
{ say("*!! ONE MILLION POINTS !!*", worm[player].colour);
celebrate();
}
print = FALSE;
break;
}
else
{ stcl_d(num, worm[player].score);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
} }
break;
case LIVESLINE:
if (worm[player].lives > STARTLIVES)
{ SetAPen(MainWindowPtr->RPort, WHITE);
if (worm[player].lives > LIVESLIMIT)
worm[player].lives = LIVESLIMIT;
}
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(num, worm[player].lives);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
}
break;
case BIASLINE:
if (worm[player].bias > 0)
{ if (worm[player].bias > BIASLIMIT)
worm[player].bias = BIASLIMIT;
SetAPen(MainWindowPtr->RPort, WHITE);
} else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(num, worm[player].bias);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
}
break;
case AMMOLINE:
if (worm[player].ammo > 0)
{ if (worm[player].ammo > AMMOLIMIT)
worm[player].ammo = AMMOLIMIT;
SetAPen(MainWindowPtr->RPort, WHITE);
} else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(num, worm[player].ammo);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
}
break;
case POWERLINE:
switch(worm[player].power)
{ case 0:
SetAPen(MainWindowPtr->RPort, worm[player].colour);
strcpy(num, STATSINGLE);
break;
case 2:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(num, STATTRIPLE);
break;
case 4:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(num, STATQUINTUPLE);
break;
case 6:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(num, STATSEPTUPLE);
break;
default:
break;
}
break;
case ARMOURLINE:
if (worm[player].armour > MODELIMIT)
worm[player].armour = MODELIMIT;
if (worm[player].mode == ARMOUR)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(num, worm[player].armour);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
}
break;
case TONGUELINE:
if (worm[player].tongue > MODELIMIT)
worm[player].tongue = MODELIMIT;
if (worm[player].mode == TONGUE)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(num, worm[player].tongue);
for (i = 0; i <= 5; i++)
if (num[i] == 0)
{ num[i] = ' ';
break;
}
break;
case SPEEDLINE:
if (worm[player].nitro)
{ SetAPen(MainWindowPtr->RPort, WHITE);
if (worm[player].speed == VERYFAST)
strcpy(num, STATVERYFAST);
else if (worm[player].speed == VERYSLOW)
strcpy(num, STATVERYSLOW);
}
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
if (worm[player].speed == FAST)
strcpy(num, STATFAST);
else if (worm[player].speed == NORMAL)
strcpy(num, STATNORMAL);
else if (worm[player].speed == SLOW)
strcpy(num, STATSLOW);
break;
default:
print = FALSE;
break;
}
if (print)
{ Move(MainWindowPtr->RPort, (FONTX * 2) + (worm[player].statx * (ENDXPIXEL + FONTX)), STARTYPIXEL + 6 + (line * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Text(MainWindowPtr->RPort, num, 6);
} }
void stopfx(ULONG receipt)
{ SBYTE i;
if (mode == FX)
for (i = 0; i <= 3; i++)
if (eversent[i] && (!(CheckIO(AudioRqPtr[i]))) && (receipt == 0L || receipt == receipter[i]))
{ AbortIO(AudioRqPtr[i]);
WaitIO(AudioRqPtr[i]);
} }
void titlescreen(void)
{ SBYTE lisa = 0, object = 0, player, segment = 0;
ULONG class, ormw = 0;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
struct Gadget* WhichGadgetPtr;
effect(FXTITLESCREEN);
blitmode(BLACK);
draw(CLOCKICON, ICONY, ANYTHING);
blitmode(NORMAL);
Forbid();
MainWindowPtr->Flags = WFLG_BORDERLESS | WFLG_ACTIVATE;
Permit();
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, STARTXPIXEL, STARTYPIXEL, ENDXPIXEL, ENDYPIXEL);
SetMenuStrip(MainWindowPtr, MenuPtr);
for (player = 0; player <= 3; player++)
GT_SetGadgetAttrs(CycleGadgetPtr[player], MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
clearkybd();
clearjoystick();
hiscores();
hiscorenames();
do
{ TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = ANIMDELAY;
SendIO(TimerRqPtr);
/* W W OOOO RRRRR MM MM
W W O O R R M M M M
W W W O O RRRRR M M M
W W W W O O R R M M
WW WW OOOO R RRR M M */
if (segment == 0)
{ worm[0].x = FIELDX / 2 - 14;
worm[0].y = 1;
worm[1].x = FIELDX / 2 - 5;
worm[1].y = 1;
worm[2].x = FIELDX / 2 + 1;
worm[2].y = 5;
worm[3].x = FIELDX / 2 + 8;
worm[3].y = 5;
}
for (player = 0; player <= 3; player++)
if (anim[player][segment].x != SENTINEL)
{ draw(worm[player].x, worm[player].y, FIRSTTAIL + ((player + ormw) % 4));
worm[player].x += anim[player][segment].x;
worm[player].y += anim[player][segment].y;
draw(worm[player].x, worm[player].y, eachworm[(player + ormw) % 4][0][anim[player][segment].x + 1 + (anim[player][segment].y + 1) * 3]);
}
if (++segment > SEGMENTS)
{ segment = 0;
if (++ormw == 1)
{ effect(FXSTAMPED);
DrawImage(MainWindowPtr->RPort, &Logo, 203, 50);
}
if (++object > LASTOBJECT)
object = 0;
say(objectdesc[object], WHITE);
Image.ImageData = ImageData[object];
DrawImage(MainWindowPtr->RPort, &Image, FIRSTDESCX, DESCY);
DrawImage(MainWindowPtr->RPort, &Image, SECONDDESCX, DESCY);
}
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ WhichGadgetPtr = (struct Gadget *) MsgPtr->IAddress;
class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch (class) {
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT))
switch (code) {
case F:
toggle(F);
break;
case M:
toggle(M);
break;
case SPACEBAR:
effect(FXCLICK);
a = FIELDEDIT;
break;
case F1:
case ALPHAONE:
case NUMERICONE:
effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[0].control < 0)
worm[0].control = 2;
} else
{ if (++worm[0].control > 2)
worm[0].control = 0;
}
GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, worm[0].control, TAG_DONE);
break;
case F2:
case ALPHATWO:
case NUMERICTWO:
effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[1].control < 0)
worm[1].control = 2;
} else
{ if (++worm[1].control > 2)
worm[1].control = 0;
}
GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, worm[1].control, TAG_DONE);
break;
case F3:
case ALPHATHREE:
case NUMERICTHREE:
effect(FXCLICK);
if (joy)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[2].control < 0)
worm[2].control = 2;
} else
{ if (++worm[2].control > 2)
worm[2].control = 0;
} }
else if (worm[2].control == NONE)
worm[2].control = AMIGA;
else
worm[2].control = NONE;
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, worm[2].control, TAG_DONE);
break;
case F4:
case ALPHAFOUR:
case NUMERICFOUR:
effect(FXCLICK);
if (worm[3].control == NONE)
worm[3].control = AMIGA;
else
worm[3].control = NONE;
GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, worm[3].control, TAG_DONE);
break;
case RETURN:
case ENTER:
a = PLAYGAME;
break;
case ESCAPE:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
case HELP:
fileabout();
break;
case INTERNATIONALONE:
if (lisa == 2)
{ say(FIRSTLISA, RED);
anykey(FALSE);
lisa = 0;
} else
lisa = 1;
break;
case INTERNATIONALTWO:
if (lisa == 1)
{ say(SECONDLISA, BLUE);
anykey(FALSE);
lisa = 0;
} else
lisa = 2;
break;
default:
break;
}
break;
case IDCMP_MENUPICK:
if (code != MENUNULL)
{ switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
effect(FXFILENEW);
newfields();
say("New done.", WHITE);
anykey(TRUE);
say(objectdesc[object], WHITE);
break;
case IN_OPEN:
effect(FXFILEOPEN);
fileopen();
say(objectdesc[object], WHITE);
break;
case IN_SAVE:
effect(FXFILESAVE);
filesaveas(FALSE);
say(objectdesc[object], WHITE);
break;
case IN_SAVEAS:
effect(FXFILESAVEAS);
filesaveas(TRUE);
say(objectdesc[object], WHITE);
break;
case IN_ABOUT:
fileabout();
break;
case IN_QUIT:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
default:
break;
}
break;
case MN_TOOLS:
a = FIELDEDIT;
break;
default:
break;
} }
break;
case IDCMP_MOUSEBUTTONS:
if (ignore)
{ if (code == SELECTUP)
ignore = FALSE;
} else a = PLAYGAME;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
case IDCMP_GADGETUP:
for (player = 0; player <= 3; player++)
if (WhichGadgetPtr == CycleGadgetPtr[player])
{ if (code == HUMAN && player == 2 && (!joy))
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
worm[2].control = NONE;
else
worm[2].control = AMIGA;
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, worm[2].control, TAG_DONE);
} else
worm[player].control = code;
break;
}
break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
default:
// IDCMP_MENUVERIFY, IDCMP_INTUITICKS
break;
} }
if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
a = PLAYGAME;
sendreadrequest();
}
if (a == PLAYGAME)
{ if (worm[0].control == NONE && worm[1].control == NONE && worm[2].control == NONE && worm[3].control == NONE)
{ say("No worms active!", WHITE);
anykey(TRUE);
a = GAMEOVER;
} }
if (CheckIO(TimerRqPtr))
draw(CLOCKICON,ICONY, CLOCK);
else
{ blitmode(BLACK);
draw(CLOCKICON, ICONY, ANYTHING);
blitmode(NORMAL);
}
WaitIO(TimerRqPtr);
} while (a == GAMEOVER);
for (player = 0; player <= 3; player++)
GT_SetGadgetAttrs(CycleGadgetPtr[player], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
Image.ImageData = ImageData[object];
blitmode(BLACK);
DrawImage(MainWindowPtr->RPort, &Image, FIRSTDESCX, DESCY);
DrawImage(MainWindowPtr->RPort, &Image, SECONDDESCX, DESCY);
blitmode(NORMAL);
if (a == FIELDEDIT)
fieldedit();
else
{ newgame();
for (player = 0; player <= 3; player++)
{ if (worm[player].control != NONE)
{ Image.ImageData = ImageData[BONUS];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (SCORELINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[LIFE];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (LIVESLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[BIAS];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (BIASLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[NITRO];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (SPEEDLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[AMMO];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (AMMOLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[POWER];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (POWERLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[ARMOUR];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (ARMOURLINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
Image.ImageData = ImageData[TONGUE];
DrawImage(MainWindowPtr->RPort, &Image, worm[player].statx * (ENDXPIXEL + FONTX), STARTYPIXEL + 1 + (TONGUELINE * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - ((LINES + 2) * FONTY))));
} else worm[player].lives = 0;
}
clearkybd();
Forbid();
MainWindowPtr->Flags = WFLG_BORDERLESS | WFLG_ACTIVATE | WFLG_RMBTRAP;
Permit();
} }
void toggle(SBYTE key)
{ PERSIST ABOOL songstarted = FALSE;
if (key == F)
{ if (mode == FX) // F in FX mode: no sound
{ freefx();
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
} else if (fxable) // F otherwise: change to FX mode
{ if (mode == MUSIC)
{ StopPlayer();
FreePlayer();
}
initsound();
mode = FX;
effect(FXFX);
} }
else // assumes key is M
{ if (mode == MUSIC) // M in MUSIC mode: no sound
{ StopPlayer();
FreePlayer();
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
} else if (musicable) // M otherwise: change to music mode
{ if (mode == FX)
freefx();
if (GetPlayer(0))
{ say("No channels for music!", RED);
anykey(TRUE);
mode = FALSE;
blitmode(BLACK);
draw(MUSICICON, ICONY, ANYTHING);
blitmode(NORMAL);
} else
{ if (songstarted)
ContModule(SongPtr);
else
{ PlayModule(SongPtr);
songstarted = TRUE;
}
mode = MUSIC;
draw(MUSICICON, ICONY, MUSIC);
} } } }
void underline(SBYTE square)
{ /* Removes old underline, draws new underline.
square: which square-type to underline, or -1 for clear only.
Squares which do not correspond to any pseudo-gadgets
(eg. objects) are converted to -1s. */
PERSIST SWORD oldy = -1;
SWORD y;
switch(square)
{
case GOLD:
y = UNDERLINEOFFSET;
break;
case SILVER:
y = UNDERLINEOFFSET + (SQUAREY * 3);
break;
case EMPTY:
y = UNDERLINEOFFSET + (SQUAREY * 6);
break;
case WOOD:
y = UNDERLINEOFFSET + (SQUAREY * 9);
break;
case STONE:
y = UNDERLINEOFFSET + (SQUAREY * 12);
break;
case ONE:
y = UNDERLINEOFFSET + (SQUAREY * 15);
break;
case TWO:
y = UNDERLINEOFFSET + (SQUAREY * 18);
break;
case START:
y = UNDERLINEOFFSET + (SQUAREY * 21);
break;
default:
square = -1;
break;
}
if (oldy != -1)
{ SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy);
Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy + SQUAREY + 3);
}
if (square != -1)
{ SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y);
Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y + SQUAREY + 3);
oldy = y;
} }
ABOOL verify(void)
{ if (modified && (EasyRequest(MainWindowPtr, &EasyStruct, NULL) == 0))
return(FALSE);
else
return(TRUE);
}
void waitasec(void)
{ Delay(50);
}
void systemsetup(void)
{ worm[0].control = NONE;
worm[1].control = HUMAN;
worm[2].control = NONE;
worm[3].control = AMIGA;
}
ABOOL ZOpen(STRPTR fieldname, ABOOL write)
{ if (FilePtr = (struct FileHandle *) Open(fieldname, MODE_READWRITE))
return TRUE;
else return FALSE;
}
ABOOL ZRead(STRPTR IOBuffer, ULONG length)
{ if (Read((BPTR) FilePtr, IOBuffer, length) == length)
return TRUE;
else return FALSE;
}
ABOOL ZWrite(STRPTR IOBuffer, ULONG length)
{ if (Write((BPTR) FilePtr, IOBuffer, length) == length)
return TRUE;
else return FALSE;
}
ABOOL ZClose(void)
{ if (Close((BPTR) FilePtr))
{ FilePtr = NULL;
return TRUE;
} else return FALSE;
}
void timeronoff(ABOOL state)
{ ;
}
// Must have blank line at EOF.